package net.protocol.diameter.avp;

import net.protocol.common.util.Bits;

import java.nio.ByteBuffer;

/**
 * <pre>
 *   Integer64
 * 		 64 bit signed value, in network byte order.  The AVP Length field
 *    	 MUST be set to 16 (20 if the 'V' bit is enabled).
 * </pre>
 *
 * @author jinhongw@gmail.com
 */
public class Integer64 extends AbstractAVP<Long> {
    public final static int DATA_LENGTH = 8;

    private final long data;

    /**
     * @param code AVP Code
     * @param data AVP Data
     */
    public Integer64(int code, long data) {
    	this(code, DEFAULT_VENDOR_ID, data);
    }

    /**
     * @param code     AVP Code
     * @param vendorId Vendor-ID
     * @param data     AVP Data
     */
    public Integer64(int code, int vendorId, long data) {
        super(code, vendorId, DATA_LENGTH);

        this.data = data;
    }

    /**
     * Creates a new <code>Integer64</code> with the given DiameterAVPHeader and source ByteBuffer
     *
     * @param header Diameter AVP Header
     * @param src The buffer from which bytes are to be retrieved
     */
    Integer64(DiameterAVPHeader header, ByteBuffer src) {
        super(header, src);

        this.data = src.getLong();
    }

    @Override
    public ByteBuffer byteMe(ByteBuffer dst) {
        super.byteMe(dst);

        dst.putLong(data);
        
        return dst;
    }

    @Override
    public Long getData() {
        return data;
    }

    @Override
    public byte[] getDataBytes() {
    	return Bits.toByteArray(data);
    }
    
    @Override
    public final boolean isGroup() {
        return false;
    }

    @Override
    public final DataFormat getType() {
        return DataFormat.Integer64;
    }

    @Override
    public String getName() {
        return DataFormat.Integer64.name();
    }

    @Override
    protected void detail(StringBuilder buf) {
        buf.append(data);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        Integer64 other = (Integer64) obj;
        if (data != other.data)
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + (int) (data ^ (data >>> 32));
        return result;
    }
}
